package com.android.fastwebview.webview

import android.content.Context
import android.content.MutableContextWrapper
import android.graphics.Bitmap
import android.net.http.SslError
import android.os.Build
import android.util.AttributeSet
import android.view.ViewGroup
import android.webkit.*
import androidx.lifecycle.*
import com.android.fastwebview.util.ContextHolder
import ren.yale.android.cachewebviewlib.WebViewCacheInterceptorInst


class FastWebView(context: Context, attributeSet: AttributeSet? = null) : WebView(context, attributeSet) {

    private var mLifecycleOwner: LifecycleOwner? = null

    private val mWebChromeClient = object : WebChromeClient() {
        override fun onProgressChanged(webView: WebView, newProgress: Int) {
            super.onProgressChanged(webView, newProgress)
        }

        override fun onReceivedTitle(webView: WebView, title: String?) {
            super.onReceivedTitle(webView, title)
        }
    }

    private val mWebViewClient = object : WebViewClient() {
        override fun shouldOverrideUrlLoading(webView: WebView, url: String): Boolean {
            return false
        }

        override fun onPageStarted(webView: WebView, url: String?, favicon: Bitmap?) {
            super.onPageStarted(webView, url, favicon)
        }

        override fun onPageFinished(webView: WebView, url: String?) {
            super.onPageFinished(webView, url)
        }

        override fun onReceivedSslError(webView: WebView, handler: SslErrorHandler?, error: SslError?) {
            super.onReceivedSslError(webView, handler, error)
        }

        override fun shouldInterceptRequest(webView: WebView, url: String): WebResourceResponse? {
            return  WebViewCacheInterceptorInst.getInstance().interceptRequest(url)
        }

        override fun shouldInterceptRequest(webView: WebView, request: WebResourceRequest): WebResourceResponse? {
            return  WebViewCacheInterceptorInst.getInstance().interceptRequest(request);
        }
    }

    init {
        webChromeClient = mWebChromeClient
        webViewClient = mWebViewClient
        initWebViewSettings(this)
    }

    private fun initWebViewSettings(webView: WebView) {
        val settings = webView.settings
        settings.run {
            javaScriptEnabled = true
            useWideViewPort = true
            loadWithOverviewMode = true
            setSupportZoom(false)
            builtInZoomControls = false
            allowFileAccess = true
            allowContentAccess = true
            loadsImagesAutomatically = true
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                safeBrowsingEnabled = false
            }
            domStorageEnabled = true
            databaseEnabled = true
            mixedContentMode = WebSettings.MIXED_CONTENT_ALWAYS_ALLOW
        }
    }

    override fun onAttachedToWindow() {
        super.onAttachedToWindow()
        mLifecycleOwner = getLifecycleOwner(context)
        mLifecycleOwner?.lifecycle?.addObserver(object : LifecycleObserver {
            @OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
            fun onCreated() {
            }

            @OnLifecycleEvent(Lifecycle.Event.ON_START)
            fun onStart() {
            }

            @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
            fun onResume() {
            }

            @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
            fun onPause() {
            }


            @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
            fun onStop() {
            }

            @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
            fun onDestroy() {
                release()
            }
        })
    }

    private fun getLifecycleOwner(context: Context): LifecycleOwner? {
        if (context is LifecycleOwner) {
            return context
        }
        if (context is MutableContextWrapper) {
            val baseContext = context.baseContext
            if (baseContext is LifecycleOwner) {
                return baseContext
            }
        }
        return null
    }

    private fun release() {
        replaceContext()
        mLifecycleOwner = null
        webChromeClient = null
        (parent as? ViewGroup)?.removeView(this)
        destroy()
    }

    /**
     * 释放webview把对应的context替换成application，否则leakcanary报持有activity实例无法释放
     */
    private fun replaceContext() {
        val contextWrapper = context as MutableContextWrapper
        contextWrapper.baseContext = ContextHolder.application
    }

}